package com.sx.dao.daoImpl;

import com.sx.dao.CategoryDao;
import com.sx.pojo.Category;
import com.sx.utils.DatabaseUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CategoryDaoImpl implements CategoryDao {
    private static final Logger logger = LogManager.getLogger(CategoryDaoImpl.class);

    /**
     * 检查给定的ID在数据库中是否存在
     * 此方法用于避免添加重复的类别ID到数据库中
     *
     * @param id 要检查的ID
     * @return 如果ID存在，则返回true；否则返回false
     */
    @Override
    public boolean checkIdExists(String id) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL查询
                String sql = "SELECT COUNT(*) FROM category WHERE id = ?";
                preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1, id);
                // 执行查询
                resultSet = preparedStatement.executeQuery();
                // 处理查询结果
                if (resultSet.next()) {
                    logger.info("类别ID存在：{}", id);
                    int count = resultSet.getInt(1);
                    // 如果查询到的记录数大于0，说明ID存在
                    return count > 0;
                }
            } else {
                // 如果数据库连接失败，记录错误日志
                logger.error("连接失败");
            }
        } catch (SQLException e) {
            // 处理数据库操作异常
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭数据库资源
            try {
                if (resultSet != null) resultSet.close();
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                // 处理关闭资源时的异常
                logger.error("关闭资源异常", e);
            }
        }
        // 默认返回值，表示ID不存在
        return false;
    }

    /**
     * 添加类别到数据库
     * <p>
     * 此方法负责将一个类别对象插入到数据库的category表中它首先尝试获取数据库连接，
     * 然后使用预编译的SQL语句插入类别信息如果插入成功，它会记录添加的类别信息并返回true；
     * 如果连接失败或插入过程中出现异常，它会记录相应的错误信息并返回false
     *
     * @param category 要添加的类别对象，包含类别ID和名称
     * @return 如果类别成功添加到数据库，返回true；否则返回false
     */
    @Override
    public boolean addCategory(Category category) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            if (connection != null) {
                // 准备SQL插入语句
                String sql = "INSERT INTO category (id, name) VALUES (?, ?)";
                preparedStatement = connection.prepareStatement(sql);
                // 设置预编译语句的参数
                preparedStatement.setString(1, category.getId());
                preparedStatement.setString(2, category.getName());
                // 记录日志信息
                logger.info("添加类别：{}", category);
                // 执行更新并根据结果返回布尔值
                return preparedStatement.executeUpdate() > 0;
            } else {
                // 如果连接失败，记录错误信息
                logger.error("连接失败");
            }
        } catch (SQLException e) {
            // 捕获并记录SQL异常信息
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭资源
            try {
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (SQLException e) {
                // 如果关闭资源时发生异常，记录错误信息
                logger.error("关闭资源异常", e);
            }
        }
        // 如果上述过程中的任何步骤失败，则返回false
        return false;
    }

    /**
     * 根据类别ID删除类别
     * 此方法尝试连接数据库并执行删除操作如果连接成功且执行了删除操作，
     * 则返回true表示删除成功；否则，记录相应的错误信息，并返回false表示删除失败
     *
     * @param id 要删除的类别的ID
     * @return 如果删除成功则返回true，否则返回false
     */
    @Override
    public boolean deleteCategoryById(String id) {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            // 检查是否成功获取数据库连接
            if (connection != null) {
                // SQL语句，用于删除指定ID的类别
                String sql = "DELETE FROM category WHERE id=?";
                // 准备SQL语句
                preparedStatement = connection.prepareStatement(sql);
                // 设置SQL语句参数
                preparedStatement.setString(1, id);
                // 执行更新操作并获取受影响的行数
                int rowsAffected = preparedStatement.executeUpdate();
                // 记录删除操作的日志信息
                logger.info("删除类别：{}", id);
                // 根据受影响的行数判断删除操作是否成功
                return rowsAffected > 0;
            } else {
                // 如果连接失败，记录错误信息
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 记录数据库操作异常信息
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭资源，释放系统资源
            try {
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                // 记录关闭资源时的异常信息
                logger.error("关闭资源异常", e);
            }
        }
        // 如果删除操作失败，返回false
        return false;
    }

    /**
     * 根据类别ID获取类别对象
     * 此方法连接数据库，查询指定ID的类别信息，并将其封装成Category对象返回
     *
     * @param id 类别的唯一标识符
     * @return 如果找到匹配的类别，则返回Category对象；否则返回null
     */
    @Override
    public Category getCategoryById(String id) {
        // 定义数据库连接，预编译语句和结果集变量
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();

            // 检查是否成功获取连接
            if (connection != null) {
                // 定义SQL查询语句，使用参数化查询防止SQL注入
                String sql = "select * from category where id=?";
                // 准备SQL执行环境
                preparedStatement = connection.prepareStatement(sql);
                // 设置查询语句的参数
                preparedStatement.setString(1, id);
                // 执行查询并获取结果集
                resultSet = preparedStatement.executeQuery();

                // 检查查询结果是否存在数据
                if (resultSet.next()) {
                    // 创建Category对象并赋值
                    Category category = new Category();
                    category.setId(resultSet.getString("id"));
                    category.setName(resultSet.getString("name"));
                    // 记录查询到的类别信息
                    logger.info("查询到类别信息：{}", category);
                    // 返回查询到的Category对象
                    return category;
                } else {
                    // 如果没有查询到数据，记录日志
                    logger.info("没有查询到类别信息");
                }
            } else {
                // 如果连接失败，记录日志
                logger.info("连接失败");
            }
        } catch (Exception e) {
            // 捕获并记录数据库操作异常
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭资源，确保资源不被泄露
            try {
                if (resultSet != null) resultSet.close();
                if (preparedStatement != null) preparedStatement.close();
            } catch (Exception e) {
                // 捕获并记录关闭资源时的异常
                logger.error("关闭资源异常", e);
            }
        }
        // 如果没有查询到类别或发生异常，返回null
        return null;
    }

    /**
     * 更新类别信息
     *
     * @param category 要更新的类别对象，包含要更新的名称和类别ID
     * @return 返回更新操作是否成功，如果成功则返回true，否则返回false
     */
    @Override
    public boolean updateCategory(Category category) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            // 获取数据库连接
            connection = DatabaseUtil.getConnection();
            // 检查数据库连接是否成功
            if (connection != null) {
                // 准备SQL语句，用于更新类别名称
                String sql = "UPDATE category SET name=? WHERE id=?";
                preparedStatement = connection.prepareStatement(sql);
                // 设置SQL语句参数
                preparedStatement.setString(1, category.getName());
                preparedStatement.setString(2, category.getId());
                // 执行更新操作
                int rowsAffected = preparedStatement.executeUpdate();
                // 记录更新日志
                logger.info("更新类别：{}", category);
                // 根据受影响的行数判断更新是否成功
                return rowsAffected > 0;
            } else {
                // 如果连接失败，记录错误日志
                logger.error("连接失败");
            }
        } catch (Exception e) {
            // 记录数据库操作异常日志
            logger.error("数据库操作异常", e);
        } finally {
            // 关闭资源，防止资源泄露
            try {
                if (preparedStatement != null) preparedStatement.close();
                if (connection != null) connection.close();
            } catch (Exception e) {
                // 记录关闭资源时的异常日志
                logger.error("关闭资源异常", e);
            }
        }
        // 默认返回值，表示更新操作失败
        return false;
    }
}
